嗨大家好我是 Chris,今天這篇將稍微解釋一下甚麼是 redux 以及它的運作方式和他能怎麼改我們的資料流,那話不多說就馬上開始吧。
首先需要聲明,在之前釋出的 hook api 中也有一個跟 Redux 相似的 api React Redux,讓 Hook 也可以作用在 Redux app 上,所以這兩者是不衝突的,細節我也還沒研究,不過感覺也是相當不錯的,而且兩者觀念基本上相同,如果對 React Redux 有興趣的先學 Redux 也不錯喔。
「The Single Immutable State Tree」- Redux 開發者是這麼說的,也就是單向不可變動的樹狀資料。
Redux 有 3 大原則,讓資料可以被更輕鬆的管理。
整個專案的 State 都將被放在同一個儲存庫 (Store)
你不能直接改變存放在 Store 的資料,相對的,你可以發出一個請求 (Action), 也就是描述事件狀態的物件,讓 Redux 改變 State。
改變 State 的方式是 pure function,也就是說你不能直接改變傳進來的參數,而是透過 Reducer 取得先前的 state 去建立一個新的 object 並回傳這個物件。
註:其實硬要的話,你還是改的掉之前的 state,不過不要啦,因為這跟 Redux 的設計有關,直接更改很可能會造成出錯。而且這可以保證你的改變都是有跡可循的,不會因為 web requset 或是不預期的 state change 造成意外的 bug 。
你可能會說,限制這麼多才不好吧,nono,有一句話叫做絕對的自制就是絕對的自由
就跟我很久前介紹過的 ESlint 一樣,透過合理的格式約束,可以減少錯誤的發生。
在 react 裡,絕大部分的動作都是透過這 3 大物件所運行的,以下將一一介紹:
也就是描述狀態的物件,基本上所有對資料的動作都會通過 Action ,它必定會含有 type 這個屬性,用來對應發送這個 Action 要做的動作,如果我們需要實作一個計數器的話,Action 會像這樣:
// action example
{
type: 'add',
list:'My first thing',
}
而 type 通常會把字串存進常數來使用他,也是為了方便,以後更新的話就不用一個一個去找了:
const ADD_LIST = 'add'
{
type: ADD_list,
list: 'My first thing',
}
除了 type 之外 Action 其他的設計都取決於你。
當然我們總不可能每次需要請求 State 時都臨時想好我們的資料結構,所以會有一個專門用來產出 Action 的 function ,並回傳回來:
function add(list){
return{
type: ADD_LIST,
list,
}
}
而這時我們就可以通過呼叫 dispatch() 傳達 Action 給 Store ,藉由比對 type 執行對應的 Reducer ,就可以得到我們想要的 State 了。
Reducer 在前面三大原則中說過,是一個 pure function ,用來處理 Action.type 對應的動作,他不會改變先前傳過來的 state,注意,這邊說的是 pure function,所以你也不能在裡面執行會造成改變其他 state 的動作(side effect),也不能使用 date.now()
、Math.random()
等等會產生新 state 的 function。
註: 複習一下,pure function 就是你丟進去甚麼,就只能產出甚麼,其他的在 Day-8 有提過。
所以按照我們的需求,Reducer 會長這樣:
initialState:{
List:[]
}
function AddList(state = initialState, action) {
switch (action.type) {
case ADD_list:
return { ...state,List:action.list };
default :
return initialState
}
可以看到我們不會改變先前的 state ,而是採用 Object Spread (...) 拆分state並重新組裝它
且可以使用 Switch case 讓 type 對應到實際的動作,如果都沒有符合,就會回傳 initialState。
而如果你有複數的 Reducer 的話,可以使用 combineReducers() 來合併 app,並 export 到 store 讓我們可以使用他,像這樣:
const Reducers = combineReducers({
AddList,
fun1,
Fun2,
Fun3,
})
Export default Reducers;
Store 是把 Action 和 Reducer 集合起來管理的物件,整個專案只會有一個 Store。
我們可以藉由 createStore()
來創建 Store:
const store = createStore(Reducers);
Store 有 3 個參數接口
store 可以使用 dispatch 傳送 action :
Dispatch(AddList('My first thing'))
且可以使用 getState() 來讀取當下 state tree 的狀態
Console.log( getState() )
// object {List:"My first thing"}
所以整個過程會像這樣:
以上是 redux 的基本架構與運作方法,明天將會帶到如何將 Redux 應用到 React 專案中。
本篇文章參考自 => https://chentsulin.github.io/redux/docs/introduction/